package com.meiyuetao.myt.customer.service;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import lab.s2jh.core.dao.BaseDao;
import lab.s2jh.core.pagination.PropertyFilter;
import lab.s2jh.core.pagination.PropertyFilter.MatchType;
import lab.s2jh.core.service.BaseService;
import lab.s2jh.ctx.FreemarkerService;

import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.meiyuetao.myt.core.constant.GenericSexEnum;
import com.meiyuetao.myt.customer.dao.InactiveUserDao;
import com.meiyuetao.myt.customer.entity.ImportUserAim;
import com.meiyuetao.myt.customer.entity.InactiveUser;
import com.meiyuetao.myt.customer.entity.InactiveUser.ImportStateEnum;
import com.meiyuetao.myt.customer.entity.SsoUser;
import com.meiyuetao.myt.job.BusinessNotifyService;

@Service
@Transactional
public class InactiveUserService extends BaseService<InactiveUser, Long> {

    @Autowired
    private InactiveUserDao inactiveUserDao;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private SsoUserService ssoUserService;
    @Autowired
    private Md5PasswordEncoder md5PasswordEncoder;
    @Autowired
    private BusinessNotifyService businessNotifyService;
    @Autowired
    private ImportUserAimService importUserAimService;
    @Autowired
    private FreemarkerService freemarkerService;

    private static final int interval = 30; // 任务的执行间隔（分）

    @Override
    protected BaseDao<InactiveUser, Long> getEntityDao() {
        return inactiveUserDao;
    }

    @Transactional
    public String autoImportUser() {
        Integer currentAim = getThisTimeAim(getRunCountOfDay());// 当次目标数
        if (currentAim == null) {
            return "ERROR:未找到当月总目标数";
        }
        long start = System.currentTimeMillis();
        // 查询currentAim 条用户数据
        List<InactiveUser> list = this.findNoImportUser(currentAim);
        if (list.isEmpty()) {
            return "ERROR:未查询到当次需导入数据";
        }
        // List
        long queryCostTime = System.currentTimeMillis() - start;// 查询耗时（毫秒）

        System.out.println(">>>>:" + new DateTime().toString("yyyy/MM/dd HH:mm:ss.SSS") + " import aim:" + currentAim + " 查询耗时:" + queryCostTime);

        /*
         * logger.debug(">>>>:"+new
         * DateTime().toString("yyyy/MM/dd HH:mm:ss.SSS")+" import aim:"
         * +currentAim+" 查询耗时:"+queryCostTime);
         */

        Set<Long> success = new HashSet<Long>();
        Set<Long> fail = new HashSet<Long>();
        for (InactiveUser user : list) {
            System.out.println(">>ID:" + user.getId());
            // 导入SSOUSer
            String mobilePhone = getMobilePhone(user.getMobile());
            if (mobilePhone != null && !"".equals(mobilePhone)) {
                List<SsoUser> ssoUsers = ssoUserService.findByFilter(new PropertyFilter(MatchType.EQ, "mobilePhone", mobilePhone));
                if (ssoUsers.isEmpty()) {
                    SsoUser ssoUser = new SsoUser();
                    ssoUser.setLoginid(mobilePhone);
                    String passwordText = RandomStringUtils.randomNumeric(8);
                    String encodedPwd = md5PasswordEncoder.encodePassword(passwordText, mobilePhone);
                    ssoUser.setPassword(encodedPwd);
                    ssoUser.setMobilePhone(mobilePhone);
                    ssoUser.setEnabled(Boolean.TRUE);
                    ssoUser.setProviderType("IYouBoxUID");
                    ssoUser.setProviderUid(md5PasswordEncoder.encodePassword(mobilePhone, UUID.randomUUID().toString()).toUpperCase());
                    ssoUser.setRegisterTime(new Date());
                    ssoUser.setLastOperationSummary(ssoUser.buildLastOperationSummary("系统自动导入，手机号" + mobilePhone));
                    ssoUser.setSysImport(Boolean.TRUE);
                    ssoUser.setReturnVisit(Boolean.FALSE);
                    ssoUser.setSex(GenericSexEnum.F);
                    ssoUser.setRealName(user.getName());
                    // 三通、云通讯现在都不能再使用了，改用云片
                    // 发送短信
                    String msg = getMsgCnt(user, passwordText);
                    // businessNotifyService.sendMsg(mobilePhone, msg);
                    businessNotifyService.sendTextSms(mobilePhone, msg);
                    // String content = "#name#=" + ssoUser.getRealName() +
                    // "&#company#=" + getEE(user) + "&#password#="
                    // + passwordText;
                    // businessNotifyService.sendSmsByYunPian(mobilePhone,
                    // "844825", content);
                    String email = user.getEmail().trim();
                    if (isEmail(email)) {
                        List<SsoUser> ssoUsers2 = ssoUserService.findByFilter(new PropertyFilter(MatchType.EQ, "email", email));
                        System.out.println(">>>E:" + email);
                        if (ssoUsers2.isEmpty()) {// 邮箱未被注册, 填邮箱, 发邮件
                            ssoUser.setEmail(email);
                            // 发送邮件
                            String eoe = getEE(user);
                            businessNotifyService.sendPushNotifyEmail(user, eoe, passwordText);
                        }
                    }
                    ssoUserService.save(ssoUser);
                    success.add(user.getId()); // 成功导入的
                } else {
                    fail.add(user.getId());// 无法导入的
                }
            } else {
                fail.add(user.getId());// 无法导入的
            }
        }
        // 置为已导入
        this.updateImportedState(success, fail);
        return "SUCCESS:成功导入：" + success.toString() + " " + success.size() + "条, 失败：" + fail.toString() + " " + fail.size() + "条";
    }

    public List<InactiveUser> findNoImportUser(int currentAim) {
        int age = 30;
        int count = 0;
        List<InactiveUser> ius = new ArrayList<InactiveUser>();
        while (true) {
            System.out.print(age + "|");
            ius.addAll(findNoImportUser(currentAim - ius.size(), age));
            if (ius.size() >= currentAim) {
                return ius;
            }
            count++;
            if (count % 2 == 0) {
                // 偶数
                age = age + count * -1;
            } else {
                // 奇数
                age = age + count;
            }
            if (age > 40)
                break;
        }
        return ius;
    }

    public List<InactiveUser> findNoImportUser(int num, int age) {
        String sql = "SELECT " + "TOP " + num + " " + "u.sid, " + "u.archive_id, " + "u.name, " + "u.sex, " + "u.birthday, " + "u.mobile, " + "u.email, " +
        /*
         * "u.region, "+ "u.address, "+
         */
        "u.educations_block, " + "u.experiences_block " + "FROM " + "myt_inactive_user u " + "WHERE " + "u.import_state='" + ImportStateEnum.WAIT + "' "
                + " AND datediff(YEAR, u.Birthday, getdate())=" + age;

        final List<InactiveUser> list = new ArrayList<InactiveUser>();
        jdbcTemplate.query(sql, new RowCallbackHandler() {

            @Override
            public void processRow(ResultSet rs) throws SQLException {
                InactiveUser u = new InactiveUser();
                u.setId(rs.getLong("sid"));
                u.setArchiveId(rs.getLong("archive_id"));
                u.setName(rs.getString("name"));
                u.setSex(rs.getBoolean("sex"));
                u.setBirthday(rs.getDate("birthday"));
                u.setMobile(rs.getString("mobile"));
                u.setEmail(rs.getString("email"));
                /*
                 * u.setRegion(rs.getString("region"));
                 * u.setAddress(rs.getString("address"));
                 */
                u.setEducationsBlock(rs.getString("educations_block"));
                u.setExperiencesBlock(rs.getString("experiences_block"));
                list.add(u);
            }
        });
        return list;
    }

    public void updateImportedState(Set<Long> ss, Set<Long> fail) {
        if (!ss.isEmpty()) {
            String sql = "UPDATE myt_inactive_user " + "SET import_state='" + ImportStateEnum.IMPORTED + "' " + "WHERE " + "sid IN ( ";
            String sids = "";
            for (Long s : ss) {
                sids += s + ",";
            }
            sids = sids.substring(0, sids.length() - 1);
            sql += sids + " )";

            jdbcTemplate.execute(sql);
        }
        // -----------------------------------------------------------
        if (!fail.isEmpty()) {
            String sql = "UPDATE myt_inactive_user " + "SET import_state='" + ImportStateEnum.CANNOT + "' " + "WHERE " + "sid IN ( ";
            String sids = "";
            for (Long f : fail) {
                sids += f + ",";
            }
            sids = sids.substring(0, sids.length() - 1);
            sql += sids + " )";

            jdbcTemplate.execute(sql);
        }
    }

    public static void main(String[] args) {
        /*
         * int age = 30; int count = 0; while(true){ System.out.print(age+"|");
         * int ius = 5; if(ius == 10){ return; } count++; if(count%2==0){ // 偶数
         * age = age+count*-1; }else{ // 奇数 age = age+count; } if(age>40)break;
         * }
         */
        String value = "hyy-2003101@meiyuetao.comaa.cn";
        if (value == null || value.length() == 0) {
            // return "";
            System.out.println("NULL");
        }
        java.util.regex.Pattern p = null;
        Matcher m = null;
        p = java.util.regex.Pattern
                .compile("\\b(^['_A-Za-z0-9-]+(\\.['_A-Za-z0-9-]+)*@([A-Za-z0-9-])+(\\.[A-Za-z0-9-]+)*((\\.[A-Za-z0-9]{2,})|(\\.[A-Za-z0-9]{2,}\\.[A-Za-z0-9]{2,}))$)\\b"); // 验证手机号
        m = p.matcher(value);
        System.out.println(m.find());

    }

    /***************************************************************************************/
    private String getMsgCnt(InactiveUser user, String passwordText) {
        String eoe = getEE(user);
        if (StringUtils.isBlank(eoe)) {
            eoe = "NONE";
        }
        Map<String, Object> dataMap = new HashMap<String, Object>();
        dataMap.put("uname", user.getName());
        dataMap.put("eoe", eoe);
        dataMap.put("password", passwordText);
        String sms = freemarkerService.processTemplateByFileName("USER_PUSH_NOTIFY_SMS", dataMap);
        System.out.println(sms);
        return sms;
    }

    public String getEE(InactiveUser user) {
        String exp = user.getExperiencesBlock();
        String edu = user.getEducationsBlock();
        if (StringUtils.isNotBlank(exp)) {
            Pattern p = Pattern.compile("[\u4e00-\u9fa5（）()]+[公司]");
            Matcher m = p.matcher(exp);
            while (m.find()) {
                String e = m.group();
                if (StringUtils.isNotBlank(e)) {
                    return e + "的同事";
                }
            }
        } else if (StringUtils.isNotBlank(edu)) {
            Pattern p = Pattern.compile("[\u4e00-\u9fa5（）()]+[大学学院学校大专中专职专]");
            Matcher m = p.matcher(edu);
            while (m.find()) {
                String e = m.group();
                if (StringUtils.isNotBlank(e)) {
                    return e + "的同学";
                }
            }
        }
        return "";
    }

    /**
     * 获取本次任务需要导入的用户数 （返回在一定范围内的随机数，当天目标准确值+runCountOfDay或-runCountOfDay）
     * 
     * @param runCountOfDay
     *            当天任务执行次数
     * @return
     */
    public Integer getThisTimeAim(int runCountOfDay) {
        DateTime dateTime = new DateTime();
        int month = dateTime.getMonthOfYear();
        // int aimOfMonth = aim.get(month);// 当月目标
        ImportUserAim importUserAim = importUserAimService.findByProperty("month", month);
        if (importUserAim == null)
            return null;
        Integer aimOfMonth = importUserAim.getAimNum();
        if (aimOfMonth == null)
            return null;
        int maxDayOfMonth = dateTime.dayOfMonth().withMaximumValue().getDayOfMonth();// 当月天数
        int aimOfDay = aimOfMonth / maxDayOfMonth;// 当天目标（准确值）
        // 当天目标（随机+runCountOfDay/-runCountOfDay）
        // int randamAimOfDay = aimOfDay + getRandom(runCountOfDay*-1,
        // runCountOfDay);
        return aimOfDay / runCountOfDay;// 当次导入目标数量 = 全天目标 ÷当天任务执行次数
    }

    public int getMin(long ms) {
        return (int) (ms / 1000 / 60);
    }

    public long getMs(int min) {
        return min * 60 * 1000;
    }

    /**
     * 获取定时任务每天执行的次数 (24-9)/执行间隔
     */
    public int getRunCountOfDay() {
        int workMinute = (24 - 9) * 60;// 工作时间（分钟）
        return workMinute / interval;// 每天执行次数 = 工作时间（分）÷执行间隔（分）
    }

    /**
     * 获取区间随机数
     * 
     * @return
     */
    public int getRandom(int min, int max) {
        return (int) (Math.random() * (max - min) + min);
    }

    public String getMobilePhone(String value) {
        if (value == null || value.length() == 0) {
            return "";
        }
        java.util.regex.Pattern p = null;
        Matcher m = null;
        p = java.util.regex.Pattern.compile("[1][3-8][0-9]{9}"); // 验证手机号
        m = p.matcher(value);
        if (m.find()) {
            return m.group();
        }
        return null;
    }

    public boolean isEmail(String value) {
        if (value == null || value.length() == 0) {
            return false;
        }
        java.util.regex.Pattern p = null;
        Matcher m = null;
        p = java.util.regex.Pattern
                .compile("\\b(^['_A-Za-z0-9-]+(\\.['_A-Za-z0-9-]+)*@([A-Za-z0-9-])+(\\.[A-Za-z0-9-]+)*((\\.[A-Za-z0-9]{2,})|(\\.[A-Za-z0-9]{2,}\\.[A-Za-z0-9]{2,}))$)\\b"); // 验证手机号
        m = p.matcher(value);
        return m.find();
    }

    public boolean isValidMobilePhone(String value) {
        if (value == null || value.length() == 0) {
            return false;
        }
        java.util.regex.Pattern p = null;
        Matcher m = null;
        boolean b = false;
        p = java.util.regex.Pattern.compile("^[1][3-8][0-9]{9}$"); // 验证手机号
        m = p.matcher(value);
        b = m.matches();
        return b;
    }
}
